<template>
  <div
    class="chart-box"
    style="width: 100%; height: 100%"
    :style="{ backgroundColor: widgetOptions.setup.backgroundColor }"
  >
    <div v-if="!chartStatus" ref="chartRef" style="width: 100%; height: 100%"></div>

    <ChartEmpty v-if="chartStatus" :chartStatus="chartStatus" />
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import { useTools } from '../../hooks/useTools'
import { useWidgetTools } from '../../hooks/useWidgetTools'
import { useSignalView } from '../../hooks/useSignalView'
import ChartEmpty from '../../components/chartEmpty.vue'

// 接收父组件传入的值
const props = defineProps({
  widgetOptions: {
    type: Object as PropType<Record<string, any>>, // 或更具体的类型
    required: true
  },
  isPreview: {
    type: Boolean,
    default: false
  }
})

const chartRef = ref<HTMLDivElement | null>(null)
let myChart: echarts.ECharts | null = null
const chartData = ref<any>(null)
const { getColorMap } = useWidgetTools()

const { toRgba } = useTools()
const mockDataUrl = '/mockdata/realtime/multiCorrelation.json'

const initChart = () => {
  if (chartRef.value) {
    // 初始化实例
    myChart = echarts.init(chartRef.value)
  }
}

// 更新配置
const updateOptions = () => {
  if (!chartData.value) return
  const { signalName, startTime, duration, value, extra } = chartData.value

  const { columns } = extra
  const labelIndex = columns.indexOf('LABEL') // 标签列索引，默认是最后一列
  const labels = value.map((item) => item[labelIndex]) // 获取所有标签
  const uniqueLabels = [...new Set(labels)] // 标签去重
  const rawData = value
  const CATEGORY_DIM_COUNT = columns.length - 1 // 维度数量，LABEL列不算在内
  const GAP = 2 // 网格间距
  const BASE_LEFT = 2 // 左边距
  const BASE_TOP = 20 //  上边距
  const GRID_WIDTH = (100 - BASE_LEFT - GAP) / (CATEGORY_DIM_COUNT - 1) - GAP - 1 // 网格宽度
  const GRID_HEIGHT = (100 - BASE_TOP - GAP) / (CATEGORY_DIM_COUNT - 1) - GAP // 网格高度
  const SYMBOL_SIZE = 10 // 点大小
  const colorMap = getColorMap(uniqueLabels) // 颜色映射

  // 生成satter数据
  function retrieveScatterData(data, dimX, dimY, index) {
    let result: any[] = []
    for (let i = 0; i < data.length; i++) {
      let item = [data[i][dimX], data[i][dimY], data[i][index]]
      result.push(item)
    }
    return result
  }
  // 生成grid
  function generateGrids() {
    let index = 0
    const grid: any[] = []
    const xAxis: any[] = []
    const yAxis: any[] = []
    const series: any[] = []

    for (let i = 0; i < CATEGORY_DIM_COUNT; i++) {
      for (let j = 0; j < CATEGORY_DIM_COUNT; j++) {
        if (CATEGORY_DIM_COUNT - i + j >= CATEGORY_DIM_COUNT) {
          continue
        }
        grid.push({
          left: BASE_LEFT + (i - 1) * (GRID_WIDTH + GAP) + '%',
          top: BASE_TOP + j * (GRID_HEIGHT + GAP) + '%',
          width: GRID_WIDTH + '%',
          height: GRID_HEIGHT + '%'
        })
        xAxis.push({
          name: j === 0 ? columns[i] : '',
          nameLocation: 'middle',
          nameGap: 30,
          splitNumber: 3,
          position: 'top',
          axisLine: {
            show: j === 0,
            onZero: false
          },
          axisTick: {
            show: j === 0,
            inside: true
          },
          axisLabel: {
            show: j === 0,
            color: props.widgetOptions.setup.xFontColor,
            fontSize: props.widgetOptions.setup.xFontSize
          },
          nameTextStyle: {
            color: props.widgetOptions.setup.xNameFontColor,
            fontSize: props.widgetOptions.setup.xNameFontSize
          },
          type: 'value',
          gridIndex: index,
          scale: true
        })
        yAxis.push({
          name: i === CATEGORY_DIM_COUNT - 1 ? columns[j] : '',
          nameLocation: 'middle',
          nameGap: 30,
          splitNumber: 3,
          position: 'right',
          axisLine: {
            show: i === CATEGORY_DIM_COUNT - 1,
            onZero: false
          },
          axisTick: {
            show: i === CATEGORY_DIM_COUNT - 1,
            inside: true
          },
          axisLabel: {
            show: i === CATEGORY_DIM_COUNT - 1,
            color: props.widgetOptions.setup.yFontColor,
            fontSize: props.widgetOptions.setup.yFontSize
          },
          nameTextStyle: {
            color: props.widgetOptions.setup.yNameFontColor,
            fontSize: props.widgetOptions.setup.yNameFontSize
          },
          type: 'value',
          gridIndex: index,
          scale: true
        })
        series.push({
          name: `${columns[i]} vs ${columns[j]}`,
          type: 'scatter',
          symbolSize: SYMBOL_SIZE,
          xAxisIndex: index,
          yAxisIndex: index,
          itemStyle: {
            color: function (param) {
              return colorMap[param.value[2]]
            }
          },
          data: retrieveScatterData(rawData, i, j, labelIndex)
        })
        index++
      }
    }
    return {
      grid,
      xAxis,
      yAxis,
      series
    }
  }
  const { grid, xAxis, yAxis, series } = generateGrids()
  const option = {
    title: {
      text: `最近${duration}秒多维度信号数据`,
      subtext: `开始时间：${startTime}`,
      left: 'center',
      textStyle: {
        color: props.widgetOptions.setup.titleColor,
        fontSize: props.widgetOptions.setup.titleFontSize
      },
      subtextStyle: {
        color: props.widgetOptions.setup.subtitleColor,
        fontSize: props.widgetOptions.setup.subtitleFontSize
      }
    },
    animation: false,
    tooltip: {
      trigger: 'item'
    },
    visualMap: {
      type: 'piecewise',
      categories: uniqueLabels,
      textStyle: {
        color: props.widgetOptions.setup.visualMapFontColor,
        fontSize: props.widgetOptions.setup.visualMapFontSize
      },
      inRange: {
        color: Object.values(colorMap)
      },
      left: 'left',
      top: 'center'
    },
    xAxis,
    yAxis,
    grid,
    series: series
  }
  console.log(option)
  myChart?.setOption(option)
  myChart?.resize()
}

const resolveData = (data: any) => {
  if (data && data.msgPack) {
    chartStatus.value = ''
    chartData.value = data.msgPack
    updateOptions()
  } else {
    chartStatus.value = 'noData'
    chartData.value = null
  }
}

const resolveMockData = (data: any) => {
  chartData.value = data
  updateOptions()
}

const { chartStatus, refreshData } = useSignalView(
  props.widgetOptions,
  props.isPreview,
  mockDataUrl,
  resolveData,
  resolveMockData
)
onMounted(() => {
  initChart()
  refreshData()
})

// 如果父组件传入的 props.value 改变，需要更新折线图颜色等
watch(
  () => props.widgetOptions,
  () => {
    if (myChart) {
      updateOptions()
    }
  },
  { immediate: true, deep: true }
)

onBeforeUnmount(() => {
  if (myChart) {
    myChart.dispose()
  }
})
</script>

<style scoped></style>
